Android M の新機能!データバインディングを使ってみた
データバインディングライブラリが公開
Google I/O 2015 で Android M が発表され、Chrome Tabs や 指紋認証、Google Pay、アクセス許可などさまざまな新機能が発表されました。楽しみですね!
- Google I/O:Android M(5.x)のプレビュー公開―指紋スキャナー、Google Pay、アクセス許可、バッテリー改善など新機能多数 | TechCrunch Japan
- Android M Developer Preview | Android Developers
今回はその中でも面白そうな新機能「データバインディング」を使ってみました。データバインディングはその名の通りデータをバインドしてくれる機能で、クラスのオブジェクトの状態の変更に応じて、XML に書いた View のプロパティを変更してくれます。
Android Studio 1.3 Developer Preview のインストール
まずは Android Studio 1.3 の Developer Preview をインストールしましょう。以下の Web ページ通りに行います。
日本語で書くとざっくり次のとおりです。
- Android Studio 1.2.2 をダウンロードする
- Settings を開き Appearance & Behavior > System Settings > Updates を開く
- チャンネルを Canary Chanel に変更する
- アップデートのチェックを行い、1.3 Developer Preview をインストールする
DataBinding ライブラリをインポートする
次に DataBinding ライブラリを Android アプリプロジェクトにインポートしましょう。まずプロジェクト直下の build.gradle を以下のようにします。公式ページ通りやったら動かなかったので、Gradle のバージョン指定に注意です。
buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.3.0-beta1' classpath "com.android.databinding:dataBinder:1.0-rc0" } } allprojects { repositories { jcenter() } }
次にアプリの Module のほうの build.gradle を以下のようにします。ここでの注意点は compileOptions です。これも無いと動きませんでした。
apply plugin: 'com.android.application' apply plugin: 'com.android.databinding' android { compileSdkVersion 'android-MNC' buildToolsVersion "23.0.0 rc1" defaultConfig { applicationId "YOUR_PROJECT_NAME" minSdkVersion 'MNC' targetSdkVersion 'MNC' versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_7 targetCompatibility JavaVersion.VERSION_1_7 } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) }
Sync して終わりです。
XML を書く
次にいよいよ実装です。ウィザードで作成された直後のプロジェクトで作成される activity_main.xml を以下のようにします。
<layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="user" type="jp.classmethod.sample.User"/> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:text="@{user.firstName}" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:id="@+id/button" android:text="ばいんど!" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> </layout>
ここで新しい書き方の登場です!いままでは XML のルートは View でしたが、それより大きな枠でもう1つ layout という階層が増えました。その中に data を入れ、variable にバインド対象のメンバーとクラスを指定しています。
なお、私の環境では XML での記述で新しい Attribute の解析エラーが出たので、Lint を無効化しました。
バインド対象のクラスを作成する
次に、バインド対象のクラスを作成しましょう。今回はサンプル通りに User クラスを作成しました。
package jp.classmethod.sample; import android.databinding.BaseObservable; import android.databinding.Bindable; public class User extends BaseObservable { private String firstName; private String lastName; public User(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } @Bindable public String getFirstName() { return this.firstName; } @Bindable public String getLastName() { return this.lastName; } public void setFirstName(String firstName) { this.firstName = firstName; notifyPropertyChanged(BR.firstName); } }
バインド可能なクラスを作成するには BaseObservable を継承します。そしてゲッターに @Bindable アノテーションを付けます。すると同パッケージに BR クラスが自動で作成されるので、今度はセッターで notifyPropertyChanged メソッドを呼び出し、どのプロパティが変化したか通知します。
次に MainActivity.java を次のように実装します。
package jp.classmethod.sample; import android.app.Activity; import android.databinding.DataBindingUtil; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import jp.classmethod.sample.databinding.ActivityMainBinding; public class MainActivity extends Activity implements View.OnClickListener { private User mUser; private ActivityMainBinding mBinding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); this.mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main); this.mUser = new User("Test", "User"); this.mBinding.setUser(this.mUser); findViewById(R.id.button).setOnClickListener(this); } @Override public void onClick(View v) { this.mUser.setFirstName("Hoge"); } }
ここでのポイントは大きく2点。1点目は ActivityMainBinding のクラスが <パッケージ名>.databinding の中に自動生成される点です。ここは恐らくコードヒントが出てこないので自分で書きましょう。2点目が DataBindingUtil を使って ActivityMainBinding クラスを生成するところです。第2引数で渡したレイアウト XML の Binding クラスが生成されます。レイアウト XML には data の中の variable の name を user としているため setUser() が自動生成されています。
ここまで実装してお気づきの人も居るかと思いますが、ちょいちょいエラーになります。
しかし、最大の注意点はエラーが表示されていてもコンパイルが成功するという点です! Developer Preview だからだと思いますが、エラーが表示されていても気にせずにビルドを実行してみてください。
以上で完成です!動かしてみると、ボタンを押したタイミングでテキストが更新されると思います。
まとめ
簡単ですが、データバインディングの事始めでした。エラーが出てしまうところは Developer Preview だからでしょうか、、
他にもデータバインディングに関する沢山の機能が追加されているので、今後も試していきたいと思います!